#include <sys/stat.h>
#include <string>
#include <cstring>
#include <iostream>
#include <semaphore.h>
#include <signal.h>
#include <pthread.h>
#include "../lib/coreutil.hpp"

namespace pland
{

static std::ostream *Log = &(std::cout);

static pthread_mutex_t Log_Lock = PTHREAD_MUTEX_INITIALIZER;

bool util_fexists(std::string strFilename)
{
	struct stat stFileInfo;
	if(stat(strFilename.c_str(),&stFileInfo) == 0)
		return true;
	else
		return false;
}

std::string log_string(std::string mess)
{
	time_t rawtime;
	char* temp;
	struct tm * timeinfo;
	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	temp = asctime (timeinfo);
	temp[strlen(temp) -1] = '\0';
	return std::string("[") + temp + "]: " + mess + "\n";
}

void utill_log(std::string message)
{
    pthread_mutex_lock(&Log_Lock);
    *Log << log_string(message) << std::flush;
    pthread_mutex_unlock(&Log_Lock);
}

bool utill_set_log(std::ostream *out)
{
    pthread_mutex_lock(&Log_Lock);
    Log = out;
    pthread_mutex_unlock(&Log_Lock);
    return true;
}

void utill_flush_log()
{
    Log->flush();
}

ssize_t utill_io_read(int fd, char* buff, size_t len)
{
	uint read_so_far = 0;
	while(read_so_far != len)
	{
		uint read_this_time = ::read(fd, buff + read_so_far, len - read_so_far);
		if(read_this_time < 0)
		{
			return read_this_time;
		}
		read_so_far+=read_this_time;
	}
	return read_so_far;
}

ssize_t utill_io_write(int fd, char* buff, size_t len)
{
	uint writen_so_far = 0;
	while(writen_so_far != len)
	{
		uint writen_this_time = ::write(fd, buff + writen_so_far, len - writen_so_far);
		if(writen_this_time < 0)
		{
			return writen_this_time;
		}
		writen_so_far+=writen_this_time;
	}
	return writen_so_far;
}

}
